/* This file is part of SurfBoard.

   SurfBoard is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   SurfBoard is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with SurfBoard.  If not, see <http://www.gnu.org/licenses/>. */

#import "SBSiteController.h"
#import "SBAppDelegate.h"
#import "SBAddressBarCell.h"
#import "WebKitPrivate.h"

@implementation SBSiteController
@synthesize webView;
- (id)init {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    // Load home page if the user told us to, otherwise open a blank page
    return [self initWithURL:[NSURL URLWithString:([defaults boolForKey:@"newWindowsOpenHome"] ?
                                                   [defaults stringForKey:@"homePage"] : @"about:blank")]];
}
- (id)initWithURL:(NSURL *)URL {
    self = [super init];
    if (self) {
        if (![NSBundle loadNibNamed:@"SBSite" owner:self])
            return nil;
        [window makeKeyAndOrderFront:self];
        [webView setCustomUserAgent:[[webView userAgentForURL:[NSURL URLWithString:@"http://local"]]
                                      stringByAppendingString:@" Version/4 Safari/528.16"]];
        [webView setPreferencesIdentifier:@"SB"];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressEstimateChanged:)
                                                     name:WebViewProgressEstimateChangedNotification object:webView];
        if ([[[URL absoluteString] pathExtension] isEqualToString:@"webarchive"])
            [[webView mainFrame] loadArchive:[[WebArchive alloc] initWithData:[NSData dataWithContentsOfURL:URL]]];
        else
            [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:URL]];
    }
    return self;
}
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}
- (void)openPanelEnded:(NSOpenPanel *)panel code:(int)code context:(void *)info {
    if (code != NSOKButton)
        [(id)info cancel];
    else {
        // Remember the directory for later open panels
        [[NSApp delegate] setLatestDirectory:[panel directory]];
        [(id)info chooseFilename:[panel filename]];
    }
}
- (BOOL)validateMenuItem:(NSMenuItem *)item {
    SEL action = [item action];
    BOOL zoomTextOnly = [[NSUserDefaults standardUserDefaults] boolForKey:@"zoomTextOnly"];
    if (action == @selector(toggleAlwaysOnTop:))
        [item setState:([window level] == NSFloatingWindowLevel ? NSOnState : NSOffState)];
    else if (action == @selector(resetZoom:))
        return (zoomTextOnly ? [webView textSizeMultiplier] : [webView pageSizeMultiplier]) != 1.0;
    if (action == @selector(zoomIn:))
        return zoomTextOnly ? [webView canMakeTextLarger] : [webView canZoomPageIn];
    if (@selector(zoomOut:))
        return zoomTextOnly ? [webView canMakeTextSmaller] : [webView canZoomPageOut];
    return YES;
}
- (BOOL)windowShouldClose:(NSNotification *)notification {
    [[[NSApp delegate] sites] removeObject:self];
    return YES;
}

#pragma mark -
#pragma mark Actions

- (IBAction)goBackForward:(id)sender {
    // If this is the forward button, go forward
    if ([sender selectedSegment])
        [webView goForward];
    else
        [webView goBack];
}
- (IBAction)goHome:(id)sender {
    [webView setMainFrameURL:[[NSUserDefaults standardUserDefaults] stringForKey:@"homePage"]];
}
- (IBAction)loadURL:(id)sender {
    NSString *string = [sender stringValue];
    if (![string length])
        return;
    // Search Google for the string if it doesn't have a period in it
    if ([string rangeOfString:@"."].length <= 0 || [string rangeOfString:@" "].length > 0)
        string = [@"http://www.google.com/search?q=" stringByAppendingString:string];
    // If there is no scheme specified, append "http://" to the front of the string
    else if ([string rangeOfString:@":"].length == 0)
        string = [@"http://" stringByAppendingString:string];
    [webView setMainFrameURL:string];
}
- (IBAction)resetZoom:(id)sender {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"zoomTextOnly"])
        [webView makeTextStandardSize:self];
    else
        [webView resetPageZoom:self];
}
- (IBAction)savePage:(id)sender {
    NSSavePanel *panel = [NSSavePanel savePanel];
    [panel setRequiredFileType:@"webarchive"];
    [panel beginSheetForDirectory:[[NSApp delegate] latestDirectory] file:nil modalForWindow:window modalDelegate:self
                   didEndSelector:@selector(savePanelEnded:code:context:) contextInfo:NULL];
}
- (void)savePanelEnded:(NSSavePanel *)panel code:(int)code context:(void *)info {
    if (code == NSOKButton)
        [[[[[webView mainFrame] dataSource] webArchive] data] writeToFile:[panel filename] atomically:YES];
}
- (IBAction)toggleAlwaysOnTop:(id)sender {
    [window setLevel:([window level] == NSFloatingWindowLevel ? NSNormalWindowLevel : NSFloatingWindowLevel)];
    [sender setState:([sender state] ? NSOffState : NSOnState)];
}
- (IBAction)zoomIn:(id)sender {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"zoomTextOnly"])
        [webView makeTextLarger:self];
    else
        [webView zoomPageIn:self];
}
- (IBAction)zoomOut:(id)sender {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"zoomTextOnly"])
        [webView makeTextSmaller:self];
    else
        [webView zoomPageOut:self];
}

#pragma mark -
#pragma mark WebFrameLoadDelegate

- (void)progressEstimateChanged:(NSNotification *)notification {
    double estimatedProgress = [[notification object] estimatedProgress];
    // If we've finished loading, set the progress to zero; we only want the progress bar to show when we're loading.
    [[addressBar cell] setProgress:estimatedProgress != 1 ? estimatedProgress : 0];
}
- (void)webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame {
    if (frame == [view mainFrame])
        [window setTitle:title];
}
- (void)webView:(WebView *)view didReceiveIcon:(NSImage *)icon forFrame:(WebFrame *)frame {
    if (frame == [view mainFrame])
        [[addressBar cell] setIcon:icon];
}
- (void)webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
    [self webView:view didFailLoadWithError:error forFrame:frame];
}
- (void)webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
    if (frame != [view mainFrame])
        return;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"error" ofType:@"xhtml"];
    NSString *template = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF16StringEncoding error:NULL];
    NSString *pageHTML = [[NSString alloc] initWithFormat:template, NSLocalizedString(@"Failed to open the page"),
                          NSLocalizedString(@"SurfBoard couldn't load the page"), [error localizedDescription], nil];
    [template release];
    [[view mainFrame] loadHTMLString:pageHTML baseURL:[NSURL URLWithString:path]];
    [pageHTML release];
}

#pragma mark -
#pragma mark WebUIDelegate

- (WebView *)webView:(WebView *)view createWebViewWithRequest:(NSURLRequest *)request {
    SBSiteController *site = [[[SBSiteController alloc] initWithURL:[request URL]] autorelease];
    [[[NSApp delegate] sites] addObject:site];
    return site.webView;
}
- (void)webView:(WebView *)view printFrameView:(WebFrameView *)frameView {
    if ([frameView documentViewShouldHandlePrint])
        [frameView printDocumentView];
    else {
        NSPrintOperation *printOperation = [frameView printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]];
        [printOperation setCanSpawnSeparateThread:YES];
        [printOperation runOperationModalForWindow:window delegate:nil didRunSelector:NULL contextInfo:NULL];
    }
}
- (void)webView:(WebView *)view runJavaScriptAlertPanelWithMessage:(NSString *)message
                                                  initiatedByFrame:(WebFrame *)frame {
    NSAlert *alert = [[[NSAlert alloc] init] autorelease];
    [alert setMessageText:[[[[frame dataSource] initialRequest] URL] host]];
    [alert setInformativeText:message];
    [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
}
- (BOOL)webView:(WebView *)view runJavaScriptConfirmPanelWithMessage:(NSString *)message
                                                    initiatedByFrame:(WebFrame *)frame {
    NSAlert *alert = [[[NSAlert alloc] init] autorelease];
    [alert setMessageText:[view mainFrameURL]];
    [alert setInformativeText:message];
    [alert addButtonWithTitle:NSLocalizedString(@"Yes")];
    [alert addButtonWithTitle:NSLocalizedString(@"No")];
    return [alert runModal] == NSAlertFirstButtonReturn ? YES : NO;
}
- (void)webView:(WebView *)view runOpenPanelForFileButtonWithResultListener:(id <WebOpenPanelResultListener>)listener {
    NSOpenPanel *panel = [[[NSOpenPanel alloc] init] autorelease];
    [panel setAllowsMultipleSelection:NO];
    [listener retain];
    [panel beginSheetForDirectory:[[NSApp delegate] latestDirectory] file:nil types:nil modalForWindow:window
                    modalDelegate:self didEndSelector:@selector(openPanelEnded:code:context:) contextInfo:listener];
}
- (void)webView:(WebView *)view setFrame:(NSRect)rect {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"javaScriptCanAdjustWindows"])
        [window setFrame:rect display:YES];
}

#pragma mark -
#pragma mark WebPolicyDelegate

- (void)webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)info request:(NSURLRequest *)request
          frame:(WebFrame *)frame decisionListener:(id <WebPolicyDecisionListener>)listener {
    if (frame == [view mainFrame]) {
        [addressBar setStringValue:[[request URL] absoluteString]];
        [backForward setEnabled:[webView canGoBack] forSegment:0];
        [backForward setEnabled:[webView canGoForward] forSegment:1];
        [[addressBar cell] setIcon:nil];
        if ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) {
            [[[NSApp delegate] sites] addObject:[[[SBSiteController alloc] initWithURL:[request URL]] autorelease]];
            [listener ignore];
        // Special case for blank page
        } else if ([[[request URL] absoluteString] isEqualToString:@"about:blank"]) {
            [listener ignore];
            NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"xhtml"];
            [[webView mainFrame] loadHTMLString:[NSString stringWithFormat:[NSString stringWithContentsOfFile:path],
                                                                            NSLocalizedString(@"A Blank Page"), nil]
                                        baseURL:[NSURL fileURLWithPath:path]];
        } else [listener use];
    }
}
@end